package com.wh.wisdomsite.xbox.utils;

import com.wh.wisdomsite.xbox.utils.calculate.CalculateTool;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 计算工具类
 * @author xk
 *
 */
public class MathUtils {

	//默认除法运算精度
    private   static   final   int   DEF_DIV_SCALE   =   2;

    private MathUtils(){}

    /**
     * 精确加法运算
     * @param s
     * @return
     */
    public static BigDecimal add(Object... s) {
        BigDecimal sum = new BigDecimal("0");
        for (Object _s : s){
            BigDecimal bs = new BigDecimal(oTs(_s));
            sum = sum.add(bs);
        }
        return sum;
    }

    /**
     * 精确除法
     * @param a
     * @param b
     * @param scale
     * @return
     */
    public static BigDecimal divide(Object a, Object b, int scale) {
        BigDecimal _a = new BigDecimal(oTs(a));
        BigDecimal _b = new BigDecimal(oTs(b));
        BigDecimal r = _a.divide(_b,scale, BigDecimal.ROUND_HALF_UP);
        return r;
    }

    public static BigDecimal divide1(Object a, Object b, int scale) {
        BigDecimal _a = new BigDecimal(oTs(a));
        BigDecimal _b = new BigDecimal(oTs(b));
        BigDecimal r = _a.divide(_b,scale, BigDecimal.ROUND_DOWN);
        return r;
    }

    /**
     * 精确除法，默认2位小数
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal divide(Object a, Object b) {
        return divide(a, b, DEF_DIV_SCALE);
    }

    public static BigDecimal divide1(Object a, Object b) {
        return divide1(a, b, DEF_DIV_SCALE);
    }

    /**
     * 精确乘法
     * @param a
     * @return
     */
    public static BigDecimal multiply(Object... a) {
        BigDecimal m = new BigDecimal("1");
        for(Object _a : a){
            BigDecimal ba = new BigDecimal(oTs(_a));
            m = m.multiply(ba);
        }
        return m;
    }

    /**
     * 精确减法
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal subtract(Object a, Object b) {
        BigDecimal _a = new BigDecimal(oTs(a));
        BigDecimal _b = new BigDecimal(oTs(b));
        BigDecimal r = _a.subtract(_b);
        return r;
    }

    /**
     * 对象转字符串
     * @param o
     * @return
     */
    public static String oTs(Object o) {
        if(null == o){
            return "0";
        }
        //字符类型
        if(o instanceof String){
            //转换成BigDecimal
            return new BigDecimal(o.toString()).toString();
        }
        //数字类型
        if(o instanceof Number){
            return o.toString();
        }
        return "0";
    }
    
    /**
     * 对象转BigDecimal对象
     * @param o
     * @return
     */
    public static BigDecimal oTd(Object o){
    	return new BigDecimal(oTs(o));
    }

    /**
     * 格式化数字 四舍五入 默认2位
     * @param str
     * @return
     */
    public static String formatStr(String str){
        return formatStr(str, 2);
    }
    
    /**
     * 格式化数字 四舍五入
     * @param str
     * @param digits 保留小数点位数
     * @return
     */
    public static String formatStr(String str, int digits){
    	java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        nf.setMinimumFractionDigits(digits);
        nf.setMaximumFractionDigits(digits);
        String a = nf.format(Double.parseDouble(str));
        return a;
    }

    public static String formatDownStr(String str, int digits){
        java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
        nf.setRoundingMode(RoundingMode.HALF_DOWN);
        nf.setGroupingUsed(false);
        nf.setMinimumFractionDigits(digits);
        nf.setMaximumFractionDigits(digits);
        String a = nf.format(Double.parseDouble(str));
        return a;
    }

    public static int compareTo(Object a, Object b){
    	return oTd(a).compareTo(oTd(b));
    }

    /**
     * 获取最小的
     * @param bigDecimals
     * @return
     */
    public static BigDecimal getMin(BigDecimal... bigDecimals){
        BigDecimal result = bigDecimals[0];
        for (BigDecimal bigDecimal : bigDecimals) {
            if(result.compareTo(bigDecimal) > 0){
                result = bigDecimal;
            }
        }
        return result;
    }




    /**
     * 预计收益
     * @param r            借款利率
     * @param timeLimit    借款期限
     * @param gzRefundWay  还款方式
     * @param isday        是否天标
     * @param timeLimitDay 借款天数
     * @param tenderMoney  投资金额
     *
     * 贵州银行(还款方式)
     * 01：一次性还本付息
     * 02：等额本息
     * 03：等额本金
     * 04：按月付息到期还本";
     * 99：其他
     * @return
     */
    public static String getEarnings(String r, Integer timeLimit, String gzRefundWay, Integer isday, Integer timeLimitDay, String tenderMoney){
        //投资1万的收益
        String earnings = "0.00";
        //年利率
        BigDecimal rate = MathUtils.divide(r, 100, 6);
        //判断：是否天标
        if(isday == 1){
            BigDecimal _divrates = divide(rate, 360, 6);
            earnings = multiply(_divrates, timeLimitDay, tenderMoney).setScale(2, BigDecimal.ROUND_DOWN).toString();
            return earnings;
        }else {
            //借款期限1个月
            if(1 == timeLimit){
                //等额本息(按月等额还本付息)
                BigDecimal _earnings = CalculateTool.Mrpi(MathUtils.oTd(tenderMoney), rate, timeLimit);
                earnings = multiply(_earnings, timeLimit).subtract(MathUtils.oTd(tenderMoney)).setScale(2, BigDecimal.ROUND_DOWN).toString();
                return earnings;
            }

            //一次性还本付息
            if("01".equals(gzRefundWay)){
                return earnings;
            }
            //等额本息(按月等额还本付息)
            if("02".equals(gzRefundWay)){
                BigDecimal _earnings = CalculateTool.Mrpi(MathUtils.oTd(tenderMoney), rate, timeLimit);
                earnings = multiply(_earnings, timeLimit).subtract(MathUtils.oTd(tenderMoney)).setScale(2, BigDecimal.ROUND_DOWN).toString();
            }
            //等额本金
            if("03".equals(gzRefundWay)){
                return earnings;
            }
            //按月付息到期还本(按月付息到期还本)
            if("04".equals(gzRefundWay)) {
                BigDecimal _earnings = CalculateTool.MrPInterest(MathUtils.oTd(tenderMoney), rate, timeLimit);
                earnings = multiply(_earnings, timeLimit).setScale(2, BigDecimal.ROUND_DOWN).toString();
                return earnings;
            }
        }
        return earnings;
    }
	
    public static void main(String[] args) {
    	BigDecimal a = new BigDecimal("5");
    	Double b = 4d;
    	String c = MathUtils.formatDownStr("19.155", 2);
    	System.out.println(c);
	}
}
